package com.qf.handle;



import com.qf.vo.ResponseCode;
import com.qf.vo.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


import java.util.List;
import java.util.stream.Collectors;


/**
 * 先定义个全局异常处理类
 * 在类上使用 @RestControllerAdvice
 *
 * @author 86155
 */
@RestControllerAdvice
@Slf4j
public class GlobalHandlerException {
    /**
     * 单个参数校验异常  40200
     *
     * @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public static ResponseResult<String> handlerConstraintViolationException(ConstraintViolationException ex) {
        String message = ex.getMessage();
        log.info(message);
        return ResponseResult.error(ResponseCode.CONSTRAINT_EXCEPTION);
    }

    /**
     * 请求dto对象校验异常
     *
     * @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult<List<String>> methodArgumentNotValidException(MethodArgumentNotValidException ex) {

        BindingResult bindingResult = ex.getBindingResult();
        List<String> collect = bindingResult.getAllErrors()
                .stream().
                        map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        ResponseResult<List<String>> responseResult = new ResponseResult<>();
        responseResult.setData(collect);
        responseResult.setStatus(ResponseCode.METHOD_ARGUMENT.getStatus());
        responseResult.setMsg(ResponseCode.METHOD_ARGUMENT.getMsg());
        return responseResult;
    }

    /**
     * 处理Get请求中 没有请求体
     * 使用@Valid 验证路径中请求实体校验失败后抛出的异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public ResponseResult<String> BindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return ResponseResult.error(ResponseCode.BIND_HANDLER);
    }

    /**
     * 未知异常
     *
     * @param throwable
     * @return
     */
    @ExceptionHandler(Throwable.class)
    public ResponseResult<String> HandlerException(Throwable throwable) {
        return ResponseResult.error(ResponseCode.UNKNOWN_EXCEPTION);
    }
}
